Conversation
4bbad7f to
3da3d3e
Compare
✅ Deploy Preview for grats ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
a9211d7 to
2a98eab
Compare
| const pkg = JSON.parse(readFileSync(resolve(__dirname, relPath), "utf8")); | ||
| if (pkg.name === "grats") return pkg.version; | ||
| } catch { | ||
| // Ignore missing/unreadable package.json files |
There was a problem hiding this comment.
Can we console.error here and ask folks to report a bug?
There was a problem hiding this comment.
Done — added console.error with a link to the issues page.
src/configSpec.ts
Outdated
| import { ConfigSpec } from "./gratsConfig.js"; | ||
|
|
||
| // Use createRequire to load JSON in ESM without `import ... with { type: "json" }` | ||
| // which is not supported by webpack's babel-loader (used by the playground). |
There was a problem hiding this comment.
Is there not some way to find a workaround in the docusorus/webpack?
There was a problem hiding this comment.
Good call. Switched to import ... from "./configSpecRaw.json" with { type: "json" } which is the standard ESM JSON import syntax. Webpack 5.97+ supports import attributes natively. Added @babel/plugin-syntax-import-attributes to the website babel config so babel-loader handles it too. No more createRequire workaround, and the cp in the build script is gone since tsc --build copies the JSON automatically with resolveJsonModule.
src/tsPlugin/initTsPlugin.ts
Outdated
| @@ -1,4 +1,5 @@ | |||
| import { version as gratsTsVersion } from "typescript"; | |||
| // @ts-ignore — typescript/lib/tsserverlibrary doesn't resolve under ESM + nodenext | |||
There was a problem hiding this comment.
This is no good. Think this means we lose all typing of TS in this file, right? Why should this change as part of moving to es modules?
There was a problem hiding this comment.
Fixed. The issue was that typescript/lib/tsserverlibrary does not resolve under ESM + nodenext. The fix is much simpler: just import from "typescript" directly — the main module exports all the same types (TS.server.PluginCreateInfo, TS.LanguageService, etc.). No @ts-ignore needed, full type safety preserved.
| "name": "grats-example-apollo-server", | ||
| "version": "0.0.0", | ||
| "description": "Example server showcasing Grats used with Apollo Server", | ||
| "type": "module", |
There was a problem hiding this comment.
Looks like we're migrating every example project to es modules. Are we really forcing all of our users to upgrade? Ideally this PR is as minimally invasive as possible and the examples could demonstrate that most consumers will NOT need to make changes to upgrade to this version.
If we really are forcing all users to upgrade or do some other workaround, maybe we need an example cjs project that shows how to achieve that wrokaround?
There was a problem hiding this comment.
Unfortunately this is unavoidable. With grats now being an ESM package ("type": "module"), TypeScript in CJS mode with module: "NodeNext" raises TS1479 even for import type from an ESM package. So any user on module: "NodeNext" (the recommended Node.js setting) needs "type": "module" in their package.json. Users with bundler-based setups (webpack/vite with moduleResolution: "bundler") don't need to change anything since bundler resolution doesn't enforce the CJS/ESM boundary.
package.json
Outdated
| "test": "tsx src/tests/test.ts", | ||
| "test-example-projects": "node src/tests/testExampleProjects.mjs", | ||
| "build": "rm -rf dist/ && tsc --build", | ||
| "build": "rm -rf dist/ && tsc --build && cp src/configSpecRaw.json dist/src/configSpecRaw.json", |
There was a problem hiding this comment.
See above comment about webpack. Would love to avoid this.
There was a problem hiding this comment.
Removed. With the switch to import ... with { type: "json" }, tsc --build copies the JSON automatically (via resolveJsonModule), so the manual cp is no longer needed.
Add `"type": "module"` to package.json and update all CJS patterns
to ESM equivalents:
- Replace `__dirname` with `import.meta.url` + `fileURLToPath`
- Replace `import { version } from "../package.json"` with readFileSync
- Replace JSON import in configSpec.ts with `createRequire`
- Update build script to copy configSpecRaw.json to dist
- Add webpack fallbacks for `url`, `fs`, `module` in website plugin
- Add `extensionAlias` to webpack config for .js→.ts resolution
- Update all example projects for ESM compatibility
- Switch website from ts-node to tsx
Summary
"type": "module"to package.json__dirnamewithimport.meta.url+fileURLToPathingratsRoot.ts,cli.ts,test.ts,buildConfigTypes.tsimport { version } from "../package.json"withreadFileSync-based version readingconfigSpec.tswithcreateRequireapproach (compatible with webpack)configSpecRaw.jsonto disturl,fs,module) andextensionAliasin website plugints-nodetotsx"type": "module"to all example projectpackage.jsonfiles.jsextensions to relative imports in example.tsfilesimportModuleSpecifierEnding: ".js"to example tsconfigsPart 2 of 5 — split from #217. Builds on #218.
Test plan
pnpm run buildpassespnpm run testpassespnpm run lintpasses